package com.gz.listener;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.gz.common.RedisConst;
import com.gz.entity.Item;
import com.gz.entity.OrderStatus;
import com.gz.service.ItemService;
import com.gz.service.OrderService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;
import com.gz.entity.Order;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 - 监听超时未支付的订单
 */
@Component
@RabbitListener(queues = "order.dlx.queue")
@Slf4j
public class OrderStatusListener {

    @Autowired
    private OrderService orderService;

    @Autowired
    private ItemService itemService;

    @Autowired
    private RedisTemplate redisTemplate;



    @SneakyThrows
    @RabbitHandler
    @Transactional  //开启事务
    public void handle(Order order, Message message, Channel channel,
                       @Header(AmqpHeaders.DELIVERY_TAG) Long deliveryTag) {
        log.info("监听到超时未支付的订单，订单号：{}", order.getOrderNum());
        // 处理订单超时未支付的逻辑
        // 1. 根据订单id查询，得到订单对象
        Order dbOrder = orderService.getById(order.getId());
        // 2. 判断订单状态：如果订单状态为1，说明是是超时未支付
        if (dbOrder.getState().equals(OrderStatus.NO_PAY.getCode())) {
            // 3. 超时未支付：修改订单状态为7，已取消
            dbOrder.setState(OrderStatus.ALREADY_CANCEL.getCode());
            orderService.updateById(dbOrder);
            // 4. 超时未支付：回退Redis中购买数量
            LambdaQueryWrapper<Item> wrapper = Wrappers.lambdaQuery(Item.class).eq(Item::getOrderId, dbOrder.getId());
            List<Item> itemList = itemService.list(wrapper);
            for (Item item : itemList) {
                //得到购买数量
                Integer buyCount = item.getBuyCount();
                //回退Redis中购买数量
                redisTemplate.opsForHash().increment(RedisConst.BOOK_STORAGE, item.getBookId().toString(), buyCount);
                log.info("回退Redis中购买数量，书id：{}，购买数量：{}", item.getBookId(), buyCount);

                //更新订单项的状态
                item.setState(OrderStatus.ALREADY_CANCEL.getCode());
                itemService.updateById(item);
            }
            log.info("订单超时未支付，已取消，订单号：{}", order.getOrderNum());
        }

        //手动确认消息
        channel.basicAck(deliveryTag, false);

    }
}
